package com.wildwolf.project.wildwolf.service;

import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.PrivacyList;
import org.jivesoftware.smack.PrivacyListListener;
import org.jivesoftware.smack.PrivacyListManager;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.PrivacyItem;
import org.jivesoftware.smack.packet.PrivacyItem.PrivacyRule;

import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import com.wildwolf.project.wildwolf.service.aidl.IPrivacyListListener;
import com.wildwolf.project.wildwolf.service.aidl.IPrivacyListManager;
import com.wildwolf.project.wildwolf.utils.LogTagUtil;

/**
 * Smack 隐私适配器
 * 
 * @author LEON
 * 
 */
public class PrivacyListManagerAdapter extends IPrivacyListManager.Stub {

	/** Class's Tag. */
	public static final String TAG = LogTagUtil
			.getLogTag(PrivacyListManagerAdapter.class);

	private final PrivacyListManager privacyListManager;

	private final RemoteCallbackList<IPrivacyListListener> privacyListListeners = new RemoteCallbackList<IPrivacyListListener>();
	/**
	 * 隐私管理监听适配器
	 */
	private final PrivacyListListenerAdapter privacyListListener = new PrivacyListListenerAdapter();

	/**
	 * 
	 * @param privacyListManager
	 *            the privacy list manager
	 */
	public PrivacyListManagerAdapter(final PrivacyListManager privacyListManager) {
		this.privacyListManager = privacyListManager;
		privacyListManager.addListener(privacyListListener);
	}

	@Override
	public void blockUser(String listName, String jid) throws RemoteException {
	}

	@Override
	public void createPrivacyList(String listName, List<PrivacyListItem> items)
			throws RemoteException {
		Log.d(TAG, "BEGIN createPrivacyList.");
		try {
			List<PrivacyItem> privacyItems = new ArrayList<PrivacyItem>();

			PrivacyItem item = new PrivacyItem(
					PrivacyItem.Type.subscription.name(), true, 2);
			item.setValue(PrivacyRule.SUBSCRIPTION_BOTH);
			privacyItems.add(item);

			privacyListManager.createPrivacyList(listName, privacyItems);
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		Log.d(TAG, "END createPrivacyList.");
	}

	@Override
	public void declineActivePrivacyList() throws RemoteException {
		try {
			privacyListManager.declineActiveList();
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
	}

	@Override
	public void declineDefaultPrivacyList() throws RemoteException {
		try {
			privacyListManager.declineDefaultList();
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
	}

	/**
	 * 编辑隐私列表
	 */
	@Override
	public void editPrivacyList(String listName, List<PrivacyListItem> items)
			throws RemoteException {
		Log.d(TAG, "BEGIN editPrivacyList.");
		try {
			privacyListManager.updatePrivacyList(listName,
					tranformPrivacyListItemsToPrivacyItems(items));
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		Log.d(TAG, "END editPrivacyList.");
	}

	/**
	 * 获取活跃用户列表
	 */
	@Override
	public String getActivePrivacyList() throws RemoteException {
		try {
			PrivacyList activePrivacyList = privacyListManager.getActiveList();
			return activePrivacyList.toString();
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		return null;
	}

	/**
	 * 获取被屏蔽的组
	 */
	@Override
	public List<String> getBlockedGroupsByList(String listName)
			throws RemoteException {
		List<String> blockedGroups = new ArrayList<String>();
		try {
			PrivacyList pL = privacyListManager.getPrivacyList(listName);
			for (PrivacyItem pI : pL.getItems()) {
				if (pI.getType().equals(PrivacyItem.Type.group)
						&& !pI.isAllow())
					blockedGroups.add(pI.getValue());
			}
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		return blockedGroups;
	}

	/**
	 * 获取被屏蔽的用户
	 */
	@Override
	public List<String> getBlockedUsersByList(String listName)
			throws RemoteException {
		List<String> blockedUsers = new ArrayList<String>();
		try {
			PrivacyList pL = privacyListManager.getPrivacyList(listName);
			for (PrivacyItem pI : pL.getItems()) {
				if (pI.getType().equals(PrivacyItem.Type.jid) && !pI.isAllow())
					blockedUsers.add(pI.getValue());
			}
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		return blockedUsers;
	}

	/**
	 * 获取默认的列表
	 */
	@Override
	public String getDefaultPrivacyList() throws RemoteException {
		try {
			PrivacyList defaultPrivacyList = privacyListManager
					.getDefaultList();
			return defaultPrivacyList.toString();
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		return null;
	}

	@Override
	public void removePrivacyList(String listName) throws RemoteException {
		try {
			privacyListManager.deletePrivacyList(listName);
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
	}

	@Override
	public void setActivePrivacyList(String listName) throws RemoteException {
		try {
			privacyListManager.setActiveListName(listName);
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
	}

	@Override
	public void setDefaultPrivacyList(String listName) throws RemoteException {
		try {
			privacyListManager.setDefaultListName(listName);
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
	}

	/**
	 * From a List of PrivacyListItem get a List of PrivacyItem.
	 * 
	 * @param items
	 *            The List of PrivacyListItem.
	 * @return A list of PrivacyItem.
	 */
	private List<PrivacyItem> tranformPrivacyListItemsToPrivacyItems(
			List<PrivacyListItem> items) {
		List<PrivacyItem> rItems = new ArrayList<PrivacyItem>();
		PrivacyItem.Type[] itemTypes = PrivacyItem.Type.values();

		for (int i = 0; i < items.size(); i++) {
			rItems.add(new PrivacyItem(
					itemTypes[items.get(i).getType()].name(), false, i));
		}

		return rItems;
	}

	/**
	 * From a List of PrivacyItem get a List of PrivacyListItem.
	 * 
	 * @param items
	 *            The List of PrivacyItem.
	 * @return A list of PrivacyListItem.
	 */
	private List<PrivacyListItem> tranformPrivacyItemsToPrivacyListItems(
			List<PrivacyItem> items) {
		List<PrivacyListItem> rItems = new ArrayList<PrivacyListItem>();

		for (int i = 0; i < items.size(); i++) {
			rItems.add(new PrivacyListItem(items.get(i).getType().ordinal(),
					items.get(i).getValue()));
		}
		return rItems;
	}

	/**
	 * 隐私列表适配器
	 * 
	 * @author LEON
	 * 
	 */
	private class PrivacyListListenerAdapter implements PrivacyListListener {
		/**
		 * Constructor.
		 */
		public PrivacyListListenerAdapter() {
		}

		@Override
		public void setPrivacyList(final String listName,
				final List<PrivacyItem> listItem) {
			int i = privacyListListeners.beginBroadcast();
			while (i > 0) {
				i--;
				try {
					privacyListListeners.getBroadcastItem(i).setPrivacyList(
							listName,
							tranformPrivacyItemsToPrivacyListItems(listItem));
				} catch (RemoteException e) {
					Log.w(TAG, e.getMessage());
				}
			}
			privacyListListeners.finishBroadcast();
		}

		@Override
		public void updatedPrivacyList(final String listName) {
			Log.d(TAG, "BEGIN updatedPrivacyList.");
			int i = privacyListListeners.beginBroadcast();
			while (i > 0) {
				i--;
				try {
					privacyListListeners.getBroadcastItem(i)
							.updatedPrivacyList(listName);
				} catch (RemoteException e) {
					Log.w(TAG, e.getMessage());
				}
			}
			privacyListListeners.finishBroadcast();
			Log.d(TAG, "END updatedPrivacyList.");
		}
	}

	@Override
	public void addPrivacyListListener(IPrivacyListListener listener)
			throws RemoteException {
		if (listener != null)
			privacyListListeners.register(listener);
	}

	@Override
	public void removePrivacyListListener(IPrivacyListListener listener)
			throws RemoteException {
		if (listener != null)
			privacyListListeners.unregister(listener);
	}

	@Override
	public List<String> getPrivacyLists() throws RemoteException {
		Log.d(TAG, "BEGIN getPrivacyLists.");
		List<String> res = new ArrayList<String>();
		try {
			PrivacyList[] registeredPrivacyLists = privacyListManager
					.getPrivacyLists();
			Log.d(TAG, "> registeredPrivacyLists size: "
					+ registeredPrivacyLists.length);
			if (registeredPrivacyLists.length > 0) {
				for (int i = 0; i < registeredPrivacyLists.length; i++) {
					res.add(registeredPrivacyLists[i].toString());
					Log.d(TAG, "> " + res.get(i) + " added.");
				}
			}
		} catch (XMPPException e) {
			Log.e(TAG, e.getMessage());
		}
		Log.d(TAG, "END getPrivacyLists.");
		return res;
	}
}
